package top.itaso.lib.alog;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Environment;
import android.text.TextUtils;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @Description ：ALog 的配置
 * @Author 叫我Aso
 * @Date 2020/11/29
 */

public final class ALogSettings {
    /**
     * ALog 输出时的 TAG，使用 .setTag() 可进行覆盖
     */
    private String TAG = "ALog";

    /**
     * ALog 本地记录文件的 日期格式 命名格式
     */
    @SuppressLint("SimpleDateFormat")
    private static SimpleDateFormat mALogFileSdf = new SimpleDateFormat("yyyy-MM-dd");

    /**
     * 记录 log 的 文件的全路径：/storage/emulated/0/Android/data/应用包名/files/alog/2024-04-03.log
     */
    private String mALogPath = "";

    /**
     * 记录 log 的 文件的根目录：/storage/emulated/0/Android/data/应用包名/files/alog/
     */
    private String mALogRootPath = "";

    /**
     * 是否打印线程名称
     */
    private boolean isShowThreadInfo = false;

    /**
     * 日志控制：是否打印
     */
    private ALogLevel mLogLevel = ALogLevel.NONE;

    /**
     * 设置 ALog 信息中打印的函数栈中的函数计数
     */
    private int methodCount = 2;
    /**
     * 负责设置 StackTraceElement[] 堆栈中函数信息打印索引控制
     */
    private int methodOffset = 0;

    private ALogAdapterImpl mALogAdapter;


    /**
     * 设置 ALog 打印时的 Tag
     *
     * @param tag 自定义 tag
     * @return ALogSettings
     */
    public ALogSettings setTag(String tag) {
        if (TextUtils.isEmpty(tag)) {
            throw new NullPointerException("请设置一个有效的 tag");
        }
        this.TAG = tag;
        return this;
    }

    /**
     * 开启异常崩溃捕获
     *
     * @param context
     */
    public ALogSettings writeCrash(Context context) {
        if (null == context) {
            throw new NullPointerException("请设置一个有效的 Context");
        }
        CrashHandler.getInstance().init(context);
        return this;
    }

    /**
     * 设置是否本地保存 ALog 输出信息
     */
    public ALogSettings writeLog(Context context) {
        Date now = new Date();
        String alogFileName = mALogFileSdf.format(now);
//        alogRootPath = context.getExternalFilesDir("alog").getAbsolutePath();
        mALogRootPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath() + File.separator + context.getPackageName() + File.separator + "alog";

        mALogPath = mALogRootPath + File.separator + alogFileName + ".log";
        return this;
    }

    /**
     * 设置是否显示线程信息
     *
     * @param isShow 是否显示线程信息
     * @return ALogSettings
     */
    public ALogSettings setShowThreadInfo(boolean isShow) {
        this.isShowThreadInfo = isShow;
        return this;
    }

    /**
     * 设置是否打印 Log 信息
     *
     * @param level
     * @return
     * @see ALogLevel
     */
    public ALogSettings setLogLevel(ALogLevel level) {
        this.mLogLevel = level;
        return this;
    }

    /**
     * 设置Log信息中打印的函数栈中的函数计数
     *
     * @param count
     */
    public ALogSettings setMethodCount(int count) {
        this.methodCount = count;
        return this;
    }

    String getTag() {
        return TAG;
    }

    /**
     * 记录 log 的 文件的全路径
     *
     * @return 如：/storage/emulated/0/Android/data/应用包名/files/alog/2024-04-03.log
     */
    String getALogPath() {
        return mALogPath;
    }

    /**
     * 当前是否显示线程名称
     *
     * @return true-显示线程信息，其中线程数受 setMethodCount(int count) 影响，false-不显示线程信息，即只打印内容
     */
    boolean isShowThreadInfo() {
        return isShowThreadInfo;
    }


    ALogLevel getLogLevel() {
        return mLogLevel;
    }


    int getMethodCount() {
        return methodCount;
    }


    int getMethodOffset() {
        return methodOffset;
    }

    /**
     * 设置 Log 信息中打印函数栈的起始位置，即用于控制需要打印哪几个(methodCount)函数
     *
     * @param methodOffset
     */
    ALogSettings setMethodOffset(int methodOffset) {
        this.methodOffset = methodOffset;
        return this;
    }

    ALogAdapterImpl getLogAdapter() {
        if (mALogAdapter == null) {
            mALogAdapter = new ALogAdapterImpl();
        }
        return mALogAdapter;
    }

    private ALogSettings setLogAdapter(ALogAdapterImpl adapter) {
        this.mALogAdapter = adapter;
        return this;
    }
}
